package plugin

import (
	"github.com/dgrijalva/jwt-go"
	"time"
)

type JwtUtils struct {
	secret string
}

func NewJwtUtils(secret string) *JwtUtils {
	m := new(JwtUtils)
	m.secret = secret
	return m
}
func (m *JwtUtils) GenerateToken(id string) (string, error) {
	token := jwt.New(jwt.SigningMethodHS256)
	claims := make(jwt.MapClaims)
	claims["sub"] = id                                       //用于在controller中确定用户
	claims["exp"] = time.Now().Add(time.Minute.Truncate(60)) //设置过期时间为72小时后
	claims["iat"] = time.Now()                               //用作和exp对比的时间
	token.Claims = claims

	tokenString, err := token.SignedString([]byte(m.secret))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

func (m *JwtUtils) ParseToken(token string) (*jwt.MapClaims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
		return m.secret, nil
	})
	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*jwt.MapClaims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}
	return nil, err

}

func (m *JwtUtils) tokenToClaims(tokenStr string) (*jwt.Token, jwt.MapClaims, error) {
	mp := jwt.MapClaims{}

	token, err := jwt.ParseWithClaims(tokenStr, &mp, func(token *jwt.Token) (interface{}, error) {
		return []byte(m.secret), nil
	})
	return token, mp, err
}

func (m *JwtUtils) Validate(tokenStr string) bool {
	token, claims, err := m.tokenToClaims(tokenStr)
	if err == nil {
		if token.Valid {
			exp := claims["exp"].(time.Time)
			iat := claims["iat"].(time.Time)
			cur := time.Now().Sub(iat).Minutes()
			d1 := exp.Sub(iat).Minutes()
			if cur > d1 {
				return false
			}
			return true
		} else {
			return false
		}
	} else {
		return false
	}
}
